package com.tfleo.mealssenger;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import com.github.ignition.core.widgets.RemoteImageView;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.tfleo.mealssenger.R;
import com.tfleo.mealssenger.adapter.FriendCheckBoxAdapter;
import com.tfleo.mealssenger.balloon.CustomOverlayItem;
import com.tfleo.mealssenger.balloon.PlacesOverlay;
import com.tfleo.mealssenger.balloon.UsersOverlay;
import com.tfleo.mealssenger.object.FriendSelection;
import com.tfleo.mealssenger.utility.DataFetcher;
import com.tfleo.mealssenger.utility.IntentExtras;
import com.tfleo.mealssenger.utility.PlaceIconFetcher;
import com.tfleo.mealssenger.utility.StaticMapFetcher;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.Secure;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import android.widget.ViewSwitcher;

public class AskHangoutActivity extends MapActivity {
	private static final int TIME_DIALOG_ID = 0;
	private static final int DATE_DIALOG_ID = 1;

	private LayoutInflater mInflater;
	private TextView vLocationName;
	private TextView vLocationCategory;
	private ListView vGuestList;
	private EditText vMessage;
	private Button vDatePicker;
	private Button vTimePicker;
	private Button vSendButton;
	private Button vBackButton;
	private ViewSwitcher vSwitcher;
	private RemoteImageView vMapImage;

	private MapView vMap;
	private MapController mMapController;
	private List<Overlay> mMapOverlays;
	private PlacesOverlay mPlacesOverlay;
	private UsersOverlay mUsersOverlay;

	private int mUserId;
	private int mLocationId;
	private String mLocationName;
	private String mDate;
	private String mTime;
	private String mLocationCategory;
	private String mLocationMap;
	private String mLocationLon;
	private String mLocationLat;

	private int mYear;
	private int mMonth;
	private int mDay;
	private int mHour;
	private int mMinute;

	private SharedPreferences mSharedPref;

	private FriendCheckBoxAdapter mGuestAdapter;

	private Context mContext;
	private String mAuth;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.add_hangout_layout);
		mContext = this;
		mInflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
		mSharedPref = getSharedPreferences(Main.USER_DATA, MODE_PRIVATE);
		mAuth = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID); //for authentication
		mUserId = mSharedPref.getInt(Main.USER_ID, 0);

		if(mUserId == 0) {
			Toast.makeText(mContext, "Error: Invalid user id!", Toast.LENGTH_SHORT).show();
			finish();
		}

		Bundle extras = getIntent().getExtras();
		if(extras != null) {
			mLocationId = extras.getInt("id", 0);
			mLocationName = extras.getString("name");
			mLocationCategory = extras.getString("category");
			mLocationMap = extras.getString("map");
			mLocationLon = extras.getString("lon");
			mLocationLat = extras.getString("lat");
		} else {
			finish();
		}
		vMap = (MapView) findViewById(R.id.map_view);
		vMap.setBuiltInZoomControls(true);

		mMapController = vMap.getController();

		mMapOverlays = vMap.getOverlays();
		mPlacesOverlay = new PlacesOverlay(this.getResources()
				.getDrawable(R.drawable.place_marker), vMap);

		mUsersOverlay = new UsersOverlay(this.getResources()
				.getDrawable(R.drawable.friend_marker), vMap);

		vSwitcher = (ViewSwitcher) findViewById(R.id.switcher);

		vMapImage = (RemoteImageView) findViewById(R.id.map_img);
		//vMapImage.setImageUrl(StaticMapFetcher.getStaticMapUrl(mLocationLon, mLocationLat));
		vMapImage.setImageUrl(StaticMapFetcher.getFromLocal(mLocationMap));
		vMapImage.loadImage();
		vMapImage.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				vSwitcher.showNext();
				//TODO: place overlay on map
			}
		});

		vLocationName = (TextView) findViewById(R.id.place_name);
		vLocationName.setText(mLocationName);
		vLocationName.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				Intent i = new Intent(mContext, PlaceActivity.class);
				i.putExtra(IntentExtras.PLACE_ID, mLocationId);
			}

		});

		vLocationCategory = (TextView) findViewById(R.id.place_category);
		vLocationCategory.setText(mLocationCategory);
		vLocationCategory.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(
				PlaceIconFetcher.getIcon(mLocationCategory)), null, null, null);

		vMessage = (EditText) findViewById(R.id.message_box);
		vGuestList = (ListView) findViewById(R.id.guest_list);
		vDatePicker = (Button) findViewById(R.id.date_picker);
		vDatePicker.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				showDialog(DATE_DIALOG_ID);
			}
		});
		vTimePicker = (Button) findViewById(R.id.time_picker);
		vTimePicker.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				showDialog(TIME_DIALOG_ID);
			}
		});


		vSendButton = (Button) findViewById(R.id.send_btn);
		vSendButton.setOnClickListener(new OnClickListener() {
			@SuppressWarnings("unchecked")
			public void onClick(View v) {
				AddInviteTask task = new AddInviteTask();
				task.execute(mGuestAdapter.getSelected());
			}
		});
		
		vBackButton = (Button) findViewById(R.id.back_btn);
		vBackButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				vSwitcher.showPrevious();
			}
		});

		FetchGuestListTask task = new FetchGuestListTask();
		task.execute(mUserId);

		final Calendar c = Calendar.getInstance();
		mYear = c.get(Calendar.YEAR);
		mMonth = c.get(Calendar.MONTH);
		mDay = c.get(Calendar.DAY_OF_MONTH);
		mHour = c.get(Calendar.HOUR_OF_DAY);
		mMinute = c.get(Calendar.MINUTE);

		mDate = mYear + "-" + mMonth + "-" + mDay;
		mTime = mHour + ":" + mMinute;
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK) && vSwitcher.getDisplayedChild() == 1) {
			finish();
		}
		return super.onKeyDown(keyCode, event);
	}

	private boolean addInvite(HashMap<Integer, Boolean> friendSelected, String message) {
		StringBuilder friendId = new StringBuilder();
		for (Map.Entry<Integer, Boolean> entry : friendSelected.entrySet()) {
			if(entry.getValue()) {
				friendId.append(entry.getKey()).append(",");
			}
		}
		if(friendId.length() > 0) {
			friendId.deleteCharAt(friendId.length()-1);
		}
		Log.i("aaa", friendId.toString());
		HttpClient httpclient = new DefaultHttpClient();
		HttpPost httppost = new HttpPost(Main.SERVER_URL + "place/" + mLocationId + "/hangout");

		try {
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
			nameValuePairs.add(new BasicNameValuePair("host_id", Integer.toString(mUserId)));
			nameValuePairs.add(new BasicNameValuePair("guests", friendId.toString()));
			//nameValuePairs.add(new BasicNameValuePair("place_id", Integer.toString(mLocationId)));
			nameValuePairs.add(new BasicNameValuePair("place_name", mLocationName));
			nameValuePairs.add(new BasicNameValuePair("message", message + " "));
			nameValuePairs.add(new BasicNameValuePair("date", mDate + " " + mTime));
			nameValuePairs.add(new BasicNameValuePair("auth", mAuth));
			httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

			// Execute HTTP Post Request
			ResponseHandler<String> responseHandler = new BasicResponseHandler();
			String responseBody = httpclient.execute(httppost, responseHandler);
			JSONObject response = new JSONObject(responseBody);
			if(response.getInt("code") > 0) {
				return true;
			} else {
				return false;
			}
		} catch(Exception e){
			e.printStackTrace();
		}

		return false;
	}

	private void drawMap(ArrayList<FriendSelection> guests) {
		mMapOverlays.clear();
		mPlacesOverlay.clear();
		mUsersOverlay.clear();

		int myLat = (int) (mSharedPref.getFloat(Main.LAST_LATITUDE, 0) * 1E6);
		int myLon = (int) (mSharedPref.getFloat(Main.LAST_LONGITUDE, 0) * 1E6);

		GeoPoint myPos = new GeoPoint(
				(int) (myLat),
				(int) (myLon));

		MapView.LayoutParams lp = new MapView.LayoutParams(
				MapView.LayoutParams.WRAP_CONTENT,
				MapView.LayoutParams.WRAP_CONTENT,
				myPos,
				MapView.LayoutParams.CENTER);

		ImageView myMarker = new ImageView(mContext);
		myMarker.setImageResource(R.drawable.my_marker);
		vMap.addView(myMarker, lp);

		int maxLat = myLat, minLat = myLat, maxLon = myLon, minLon = myLon;

		for(int i = 0; i < guests.size(); i++) {
			FriendSelection u = guests.get(i);

			GeoPoint otherPos = new GeoPoint(
					(int) (u.getLatitude()* 1E6),
					(int) (u.getLongitude() * 1E6));
			CustomOverlayItem thisOverlay = new CustomOverlayItem(otherPos, u.id,
					u.name, "", u.imageUrl, true);
			maxLat = Math.max(maxLat, (int)(u.getLatitude() * 1E6));
			minLat = Math.min(minLat, (int)(u.getLatitude() * 1E6));

			maxLon = Math.max(maxLon, (int)(u.getLongitude() * 1E6));
			minLon = Math.min(minLon, (int)(u.getLongitude() * 1E6));

			mUsersOverlay.addOverlay(thisOverlay);

		}
		mMapOverlays.add(mUsersOverlay);
		//curPlace = result.p.get(0);
		float lat, lon;
		GeoPoint otherPos = new GeoPoint(
				(int) ((lat = Float.parseFloat(mLocationLat)) * 1E6),
				(int) ((lon = Float.parseFloat(mLocationLon)) * 1E6));
		CustomOverlayItem thisOverlay = new CustomOverlayItem(otherPos, mLocationId,
				mLocationName, "", mLocationCategory, false);

		maxLat = Math.max(maxLat, (int)(lat * 1E6));
		minLat = Math.min(minLat, (int)(lat * 1E6));

		maxLon = Math.max(maxLon, (int)(lon * 1E6));
		minLon = Math.min(minLon, (int)(lon * 1E6));

		mPlacesOverlay.addOverlay(thisOverlay);
		mMapOverlays.add(mPlacesOverlay);

		mMapController.animateTo(new GeoPoint((maxLat + minLat)/2, 
				(maxLon + minLon)/2 ));
		double fitFactor = 1.5;
		mMapController.zoomToSpan((int) (Math.abs(maxLat - minLat) * fitFactor), 
				(int)(Math.abs(maxLon - minLon) * fitFactor));
		vMap.invalidate();

	}

	

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DATE_DIALOG_ID:
			return new DatePickerDialog(this,
					mDateSetListener,
					mYear, mMonth, mDay);
		case TIME_DIALOG_ID:
			return new TimePickerDialog(this,
					mTimeSetListener, mHour, mMinute, false);
		}
		return null;
	}

	private DatePickerDialog.OnDateSetListener mDateSetListener =
			new DatePickerDialog.OnDateSetListener() {
		public void onDateSet(DatePicker view, int year, int month, int day) {
			mYear = year;
			mMonth = month + 1;
			mDay = day;

			vDatePicker.setText(new StringBuilder()
			.append(mYear).append("/")
			.append(mMonth).append("/")
			.append(mDay));

			mDate = mYear + "-" + mMonth + "-" + mDay; 
		}
	};

	private TimePickerDialog.OnTimeSetListener mTimeSetListener =
			new TimePickerDialog.OnTimeSetListener() {
		public void onTimeSet(TimePicker view, int hour, int minute) {
			mHour = hour;
			mMinute = minute;
			vTimePicker.setText(new StringBuilder()
			.append(pad(mHour)).append(":")
			.append(pad(mMinute)));

			mTime = mHour + ":" + mMinute;
		}
	};

	private static String pad(int c) {
		if (c >= 10)
			return String.valueOf(c);
		else
			return "0" + String.valueOf(c);
	}

	private class FetchGuestListTask extends AsyncTask<Integer, Void, ArrayList<FriendSelection>> {
		@Override
		protected ArrayList<FriendSelection> doInBackground(Integer... id) {
			return DataFetcher.fetchFriendSelection(id[0], id[0], mAuth );
		}

		@Override
		protected void onPostExecute(ArrayList<FriendSelection> result) {
			mGuestAdapter = new FriendCheckBoxAdapter(mContext, 
					R.layout.add_share_list_entry, R.id.name, result, mInflater);
			vGuestList.setAdapter(mGuestAdapter);
			
			drawMap(result);
		}
	}

	private class AddInviteTask extends AsyncTask<HashMap<Integer, Boolean>, Void, Boolean> {
		@Override
		protected Boolean doInBackground(HashMap<Integer, Boolean>... data) {
			return addInvite(data[0], vMessage.getText().toString());
		}

		@Override
		protected void onPostExecute(Boolean result) {
			if(result) {
				Toast.makeText(mContext, "Invitation sent!", Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(mContext, "Error: Server request failed", Toast.LENGTH_SHORT).show();
			}
			finish();
		}	
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
}
